import React, {FC, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import "./index.less";
import {Button, Checkbox, Flex, Form, Input, InputRef, message, Space, Tooltip, Typography} from "antd";
import {CloseSquareFilled, LockOutlined, MailOutlined, PhoneOutlined, SafetyOutlined} from "@ant-design/icons";
import {FormattedMessage, history, Link, useIntl} from "@@/exports";
import classNames from "classnames";
import {nanoid} from "nanoid";
import {DEFAULT_LOGIN_PATH as LOGIN_PATH} from "@kf-web-library/utils/es/constants";
import {HxConfigContext} from "@/layouts/HxConfigContext";
import {useRequest} from "ahooks";
import * as API from "@/services";
import {StatelessCaptchaReq} from "@/services";
import lodash from "lodash";
import {KfCaptcha, KfCaptchaAction} from "@kf-web-library/forms";
import queryString from "query-string";
import {CommonRegex} from "kf-web-library";
import KfCountdownButton from "@kf-web-library/components/es/KfCountdownButton/KfCountdownButton";
import HxIcon from "@/components/HxIcon";

type RegisterType = "email" | "mobile";

interface RegisterPageProps {
}


const RegisterPage: FC<RegisterPageProps> = (props) => {
  const intl = useIntl();
  const registerBy: RegisterType = useMemo(() => {
    const {registerType} = queryString.parse(location?.search);
    let ret = lodash.isArray(registerType) ? registerType[0] : registerType;
    return ret === "mobile" ? "mobile" : "email";
  }, [location?.search]);

  const setRegisterBy = useCallback((registerType: RegisterType) => {
    history.push({
      pathname: ``,
      search: queryString.stringify({
        ...queryString.parse(location.search),
        registerType: registerType,
      })
    });
  }, [location?.search]);

  const registerByDesc = registerBy === "email" ?
    {name1: intl.formatMessage({id: `text.email`}), name2: intl.formatMessage({id: `text.email-verification-code`})} :
    {name1: intl.formatMessage({id: `text.mobile`}), name2: intl.formatMessage({id: `text.sms-verification-code`})};
  const {authedRedirect} = useContext(HxConfigContext);
  const [form] = Form.useForm();

  const captchaRef = useRef<KfCaptchaAction | undefined>();
  const vCodeInputRef = useRef<InputRef>(null);


  const registerReq = useRequest((p) => API.register(p), {
    manual: true,
    onError: (e: any) => {
      if (e?.response?.data?.bizcode == 409011) {
        form.setFieldValue("verificationCode", "")
        vCodeInputRef.current?.focus?.();
      }
    },
    onSuccess: (resp) => {
      if (resp.flag) {
        history.push({
          pathname: `/login`,
          search: authedRedirect ? queryString.stringify({redirect: authedRedirect}) : "",
        });
      }
    }
  })

  const sendVerificationCodeReq = useRequest((emailOrMobile: string, captcha: StatelessCaptchaReq) => API.sendVerificationCode({
    emailOrMobile,
    captcha,
    verificationCodeType: "REGISTER",
  }), {
    manual: true,
    onError: (e: any) => {
      if (e?.response?.data?.bizcode == 409006) {
        captchaRef.current?.refresh();
      }
      form.setFieldValue("captcha", "")
      captchaRef.current?.focus?.();
    },
    onSuccess: (resp, p) => {
      if (resp.flag) {
        if (lodash.isString(resp.data)) {
          //测试环境, 验证码会直接返回出来
          form.setFieldValue("verificationCode", resp.data)
        }
        message.success(<>已发送至<Typography.Text type="success">{p[0]}</Typography.Text>，请注意接收</>);
      }
    }
  })

  useEffect(() => {
    form.setFieldValue("captcha", undefined);
    captchaRef.current?.refresh();

    const emailOrMobileValue = form.getFieldValue('emailOrMobile');
    if (emailOrMobileValue) {
      // 解决registerBy切换后, 表单验证error没有正确的被切换, ps: AntDesign的Form.Item在首次触发验证(错误)后如果值没有变再次触发会保留之前错误提也不会变
      form.setFieldValue("emailOrMobile", undefined);
      setTimeout(() => {
        form.setFieldValue("emailOrMobile", emailOrMobileValue);
        form.validateFields(['emailOrMobile'], {dirty: true});
      })
    }

  }, [registerBy]);


  return (
    <div className={"register-page-container"}>
      <Space className={"register-type-wrapper"} size={56}>
        <a className={classNames({"active": registerBy === "email"})}
           onClick={() => setRegisterBy("email")}>
          <FormattedMessage id="text.register-by-mobile"/>
        </a>
        <a className={classNames({"active": registerBy === "mobile"})}
           onClick={() => setRegisterBy("mobile")}>
          <FormattedMessage id="text.register-by-email"/>
        </a>
      </Space>
      <Form
        form={form}
        className={"tooltip-feedback-form"}
        feedbackIcons={({errors}) => ({
          error: (
            <Tooltip
              key="tooltipKey"
              title={errors?.map((error) => <div key={nanoid()}>{error}</div>)}
              color="red"
            >
              <CloseSquareFilled/>
            </Tooltip>
          ),
        })}
        onFinishFailed={(errorInfo) => {
          const {errorFields} = errorInfo;
          // 如果只有一项错误，并且是 agreeAgreement 字段
          if (errorFields.length === 1 && errorFields[0].name.includes("agreeAgreement")) {
            message.warning(intl.formatMessage(
              {id: `text.user-privacy-policy-tip`},
              {text: intl.formatMessage({id: "text.user-privacy-policy"})}
            ));
          }
        }}
        onFinish={(values) => {
          registerReq.run(lodash.omit(values, ["captcha"]));
        }}
      >
        <Form.Item
          name="emailOrMobile"
          help=""
          hasFeedback={true}
          rules={[
            {
              required: true,
              message: intl.formatMessage({id: `validation.require`}, {text: registerByDesc.name1}),
            },
            () => ({
              validator(_, value) {
                if (!value) return Promise.resolve();

                if (registerBy === 'email') {
                  if (!CommonRegex.EMAIL_NUMBER_REGEX.test(value)) {
                    return Promise.reject(intl.formatMessage({id: `validation.email_require`}));
                  }
                } else if (registerBy === 'mobile') {
                  if (!CommonRegex.CHINA_MOBILE_NUMBER_REGEX.test(value)) {
                    return Promise.reject(intl.formatMessage({id: `validation.mobile_require`}));
                  }
                }
                return Promise.resolve();
              },
            }),
          ]}
        >
          <Input prefix={registerBy === "email" ? <MailOutlined/> : <PhoneOutlined/>}
                 size={"large"} placeholder={intl.formatMessage({id: `validation.require`}, {text: registerByDesc.name1})}/>
        </Form.Item>
        <Form.Item
          name="captcha"
          help=""
          hasFeedback={true}
          rules={[{required: true, message: intl.formatMessage({id: `validation.captcha_require`})}]}
        >
          <KfCaptcha.Input
            actionRef={captchaRef}
            bizType={"REGISTER"}
            prefix={<SafetyOutlined/>}
            size={"large"}
            placeholder={intl.formatMessage({id: `validation.captcha_require`})}
          />
        </Form.Item>

        <Form.Item noStyle shouldUpdate={true}>
          {({getFieldValue}) => {
            const emailOrMobile = getFieldValue("emailOrMobile");
            const captcha = getFieldValue("captcha");
            const enabledSendVerificationCode = emailOrMobile?.length > 5 && captcha?.input?.length > 1;

            return (
              <Form.Item help="" style={{marginBottom: 56}}>
                <Flex vertical={false} gap={6}>
                  <Form.Item
                    name="verificationCode"
                    help=""
                    noStyle
                    hasFeedback={true}
                    // extra="系统已经发送验证码到填写的邮箱，若未收到验证码，请到邮件垃圾箱中查找一下。"
                    rules={[{
                      required: true,
                      message:   intl.formatMessage(
                        {id: `validation.verificationCode_require`},
                        {text: registerByDesc.name2},
                      ),
                    }]}
                  >
                    <Input ref={vCodeInputRef} maxLength={6} prefix={<HxIcon type={"hxicon-yanzhengma"}/>} size={"large"}
                           placeholder={intl.formatMessage(
                             {id: `validation.verificationCode_require`},
                             {text: registerByDesc.name2},
                           )}/>
                  </Form.Item>

                  <KfCountdownButton color="primary"
                                     variant="filled"
                                     size={"large"}
                                     disabled={!enabledSendVerificationCode}
                                     style={{width: 160, fontSize: 16}}
                                     onClick={() => {
                                       /*if (!emailOrMobile) {
                                         message.error(`请先输入${registerByDesc.name1}`);
                                         return;
                                       }*/
                                       return new Promise((resolve, reject) => {
                                         sendVerificationCodeReq.runAsync(emailOrMobile, captcha)
                                           .then(resp => {
                                             return resp.flag ? resolve() : reject()
                                           }).catch((error) => {
                                             reject();
                                             form.setFieldValue("captcha", "")
                                             captchaRef.current?.focus?.();
                                           }
                                         );
                                       })

                                     }}
                  >
                    <FormattedMessage id="text.send" values={{what: registerByDesc.name2}}/>
                  </KfCountdownButton>
                </Flex>
              </Form.Item>
            )
          }}

        </Form.Item>


        <Form.Item
          name="passwd"
          help=""
          hasFeedback={true}
          extra={intl.formatMessage({id: `validation.passwd_pattern`})}
          rules={[
            {required: true, message: intl.formatMessage({id: `validation.passwd_require`})},
            {
              pattern: CommonRegex.ACCOUNT_PWD_REGEX,
              message: intl.formatMessage({id: `validation.passwd_pattern`}),
            }
          ]}
        >
          <Input.Password prefix={<LockOutlined/>} size={"large"} placeholder={intl.formatMessage({id: `validation.passwd_require`})}/>
        </Form.Item>
        <Form.Item
          name="rePasswd"
          help=""
          hasFeedback={true}
          rules={[
            {required: true, message: intl.formatMessage({id: `validation.rePasswd_require`})},
            ({getFieldValue}) => ({
              validator(rule, value) {
                if (!value || getFieldValue('passwd') === value) {
                  return Promise.resolve();
                }
                return Promise.reject(intl.formatMessage({id: `validation.rePasswd_same`}));
              },
            }),
          ]}
        >
          <Input.Password prefix={<LockOutlined/>} size={"large"} placeholder={intl.formatMessage({id: `validation.rePasswd_require`})}/>
        </Form.Item>
        <Form.Item style={{marginTop: 24, marginBottom: 0}}>
          <Button
            className={'login-submit-btn'}
            type="primary"
            htmlType="submit"
            size={"large"}
            block={true}
            loading={registerReq.loading}
          >
            <FormattedMessage id="text.register"/>
          </Button>
        </Form.Item>
        <Form.Item
          name="agreeAgreement"
          valuePropName="checked"
          label={null}
          rules={[
            {
              validator: (_, value) =>
                value ? Promise.resolve() : Promise.reject(),
            },
          ]}
        >
          <Checkbox className={"user-privacy-policy-checkbox"}>
            <FormattedMessage id="text.user-privacy-policy-accept" values={{
              userPrivacyPolicy: (
                <Link to={`/privacy-policy`}
                      target={"_blank"}
                >
                  <FormattedMessage id="text.user-privacy-policy"/>
                </Link>
              ),
              legalAgreement: (
                <Link to={`/legal-agreement`}
                      target={"_blank"}
                >
                  <FormattedMessage id="text.legal-agreement"/>
                </Link>
              )
            }}/>
          </Checkbox>
        </Form.Item>


        <Form.Item>
          <Flex vertical={false} gap={6} justify={"space-between"}>
            <div>
              <FormattedMessage
                id="text.account-desc1"
                values={{
                  btn: (
                    <Link to={{
                      pathname: LOGIN_PATH,
                      search: authedRedirect ? queryString.stringify({redirect: authedRedirect}) : "",
                    }}>
                      <FormattedMessage id="text.login"/>
                    </Link>
                  )
                }}
              />
            </div>
            <div>

            </div>
          </Flex>
        </Form.Item>
      </Form>
    </div>
  );
};

export default RegisterPage;
